﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Cryptography;
using System.Text;

namespace AEM.Utils
{
    public static class StringHelper
    {
        /// <summary>
        /// Array To String
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string toString<T>(this T[] input)
        {
            StringBuilder sb = new StringBuilder();
            foreach (T i in input)
            {
                if (typeof(T) == typeof(byte))
                    sb = sb.Append(Convert.ToByte(i).ToString("X2"));
                else
                    sb = sb.Append(i.ToString());
            }
            return sb.ToString();
        }
        public static string toString<T>(this T[] input, string split)
        {
            StringBuilder sb = new StringBuilder();
            foreach (T i in input)
            {
                if (typeof(T) == typeof(byte))
                    sb = sb.Append(Convert.ToByte(i).ToString("X2"));
                else
                    sb = sb.Append(i.ToString());
                sb = sb.Append(split);
            }
            return sb.ToString();
        }

        public static int toInt32(this string input)
        {
            try { return Convert.ToInt32(input); }
            catch { return 0; }
        }
        public static int toInt32(this double input)
        {
            try { return Convert.ToInt32(input); }
            catch { return 0; }
        }
        public static long toInt64(this double input)
        {
            try { return Convert.ToInt64(input); }
            catch { return 0; }
        }

        public static DateTime toDateTime(this string input)
        {
            try { return Convert.ToDateTime(input); }
            catch { return DateTime.MinValue; }
        }

        public static string Join<T>(this T[] array, char splitChar)
        {
            return array.Join(splitChar.ToString());
        }

        public static string Join<T>(this T[] array, string splitStr)
        {
            StringBuilder sb = new StringBuilder();
            foreach (T info in array)
            {
                if (null == info) sb.AppendFormat("{0}{1}", "", splitStr);
                else
                    sb.AppendFormat("{0}{1}", info.ToString(), splitStr);
            }
            return sb.ToString().Left(sb.Length - splitStr.Length);
        }

        /// <summary>
        /// 字符串倒序
        /// </summary>
        /// <param name="input">字符串</param>
        /// <returns>倒序字符串</returns>
        public static string Reverse(this string input)
        {
            return new string(input.ToCharArray().Reverse().ToArray());
        }

        /// <summary>
        /// 取左边Length
        /// </summary>
        /// <param name="input"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string Left(this string input, int length)
        {
            if (string.IsNullOrEmpty(input)) return "";
            if (length < input.Length) return input.Substring(0, length);
            return input;
        }

        /// <summary>
        /// 取右边Length
        /// </summary>
        /// <param name="input"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public static string Right(this string input, int length)
        {
            return input.Right(length, ' ').Trim();
        }

        /// <summary>
        /// 取右边Length
        /// </summary>
        /// <param name="input"></param>
        /// <param name="length"></param>
        /// <param name="supplement">长度不度时(前)补位字符</param>
        /// <returns></returns>
        public static string Right(this string input, int length, char supplement)
        {
            if (string.IsNullOrEmpty(input)) return "";
            if (input.Length >= length) return input.Substring(input.Length - length);

            return input.Insert(0, new string(supplement, length - input.Length));
        }
        /// <summary>
        /// 字符串转换成整型数组
        /// e.g. int[] ids = StringHelper.StrToInt("1,2,,3,4,5", new char[] {','});
        /// </summary>
        /// <param name="input">字符串</param>
        /// <param name="split">间隔符 e.g. new char[] {','}</param>
        /// <returns></returns>
        public static int[] StrToInt(string input, char[] split)
        {
            int[] intarray = null;
            string[] tmp = input.Split(split, StringSplitOptions.RemoveEmptyEntries);
            intarray = Array.ConvertAll<string, int>(tmp, delegate(string s) { return int.Parse(s); });
            return intarray;
        }

        /// <summary>
        /// 字符串转换成整形数组
        ///e.g. string input = "1,2,3,4,5,6";int[] arr = input.toIntArray();
        /// </summary>
        /// <param name="input">string like "1,2,3,4,5,6"</param>
        /// <returns>int[]</returns>
        public static int[] toIntArray(this string input)
        {
            return StrToInt(input, new char[] { ',' });
        }

        public static byte[] toByteArray(this string input)
        {
            return input.toByteArray(NumberStyles.Integer);
        }

        public static byte[] toByteArray(this string input, NumberStyles style)
        {
            byte[] ret = null;

            int strlen = input.Length;
            if (strlen.isOdd())
            {
                input = "0" + input;
                strlen++;
            }
            int len = strlen / 2;
            ret = new byte[len];
            for (int i = 0; i < strlen; i += 2)
            {
                ret[i / 2] = byte.Parse(input.Substring(i, 2), style);
            }
            return ret;
        }

        /// <summary>
        /// 判断是否为奇数
        /// e.g. bool ret=n.isOdd();
        /// </summary>
        /// <param name="n">整数</param>
        /// <returns>true or false</returns>
        public static bool isOdd(this int n)
        {
            return Convert.ToBoolean(n % 2);
        }

        /// <summary>
        /// 判断字符串是否为数字字符串
        /// e.g. bool ret = input.isNumeric();
        /// </summary>
        /// <param name="input">字符串</param>
        /// <returns>true or false</returns>
        public static bool isNumeric(this string input)
        {
            System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"^\d+$");
            if (rex.IsMatch(input))
                return true;
            else
                return false;
        }

        public static bool checkUserName(this string input)
        {
            System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"^[a-zA-Z0-9]{6,16}$");//@"^[a-zA-Z]\w{5,16}$"
            if (rex.IsMatch(input))
                return true;
            else
                return false;
        }

        public static bool checkPwd(this string input)
        {
            System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"^[a-zA-Z0-9]{6,16}$");
            if (rex.IsMatch(input))
                return true;
            else
                return false;
        }

        public static bool checkActualFloor(this string input)
        {
            System.Text.RegularExpressions.Regex rex = new System.Text.RegularExpressions.Regex(@"^[A-Za-z0-9,-]+$");
            if (rex.IsMatch(input))
                return true;
            else
                return false;
        }

        /// <summary>
        /// 将数字字符串转化成数字
        /// </summary>
        /// <param name="input">字符串</param>
        /// <returns>int</returns>
        public static int toNumeric(this string input)
        {
            try
            {
                return Convert.ToInt32(input.Trim());
            }
            catch
            {
                return 0;
            }

        }
        /// <summary>
        /// MD5 加密
        /// </summary>
        /// <param name="input">string</param>
        /// <returns>MD5 string</returns>
        public static string toMD5(this string input)
        {
            using (MD5CryptoServiceProvider provider = new MD5CryptoServiceProvider())
            {
                return BitConverter.ToString(provider.ComputeHash(Encoding.UTF8.GetBytes(input))).Replace("-", "").ToLower(CultureInfo.CurrentCulture);
            }
        }

        /// <summary>
        /// Enum TO List 枚举转成List
        /// </summary>
        /// <typeparam name="T">枚举对象</typeparam>
        /// <returns></returns>
        public static List<T> EnumToList<T>()
        {
            Type enumType = typeof(T);

            // Can't use type constraints on value types, so have to do check like this
            if (enumType.BaseType != typeof(Enum))
                throw new ArgumentException("T must be of type System.Enum");

            return new List<T>(Enum.GetValues(enumType) as IEnumerable<T>);
        }



    }
}
